package com.gd.iot.energy.service.systemadmin.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.systemadmin.AreaOrganizationPOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.systemadmin.AreaOrganizationPO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.systemadmin.dto.AreaOrganizationSaveDTO;
import com.gd.iot.energy.pojo.systemadmin.vo.AreaOrganizationPageVO;
import com.gd.iot.energy.pojo.systemadmin.vo.AreaOrganizationVO;
import com.gd.iot.energy.pojo.systemadmin.vo.EnumVO;
import com.gd.iot.energy.service.systemadmin.AreaOrganizationService;
import com.gd.iot.energy.util.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 区域  服务实现类
 * </p>
 *
 * @author 自动生成
 * @since 2020-08-06
 */
@Service
public class AreaOrganizationServiceImpl extends ServiceImpl<AreaOrganizationPOMapper, AreaOrganizationPO> implements AreaOrganizationService {

    @Resource
    private AreaOrganizationPOMapper areaOrganizationPOMapper;

    /**
     * 表头文件
     */
    private static final String AREA_LIST_COLUMN_FILE_NAME = "systemadmin/areaOrganization_list.column";

    /**
     * 当前用户区域
     * @return
     */
    @Override
    public List<AreaOrganizationVO> getAreaOrganizationVOs() {
        QueryWrapper<AreaOrganizationPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        boolean superAdmin = CurrentUserUtil.isSuperAdmin();
        List<Integer> currentUserAreaIds = CurrentUserUtil.getCurrentUserAreaIds();
        if(!superAdmin){
            if(currentUserAreaIds.isEmpty()) {
                return new ArrayList<>();
            }else{
                List<Long> areaIdsIncludeChild = new ArrayList<>();
                for (Integer currentUserAreaId : currentUserAreaIds) {
                    areaIdsIncludeChild.addAll(getChildAreaIdsWithoutRights(currentUserAreaId));
                }

                queryWrapper.in("id", areaIdsIncludeChild);
            }
        }

        List<AreaOrganizationPO> areaOrganizationPOS = areaOrganizationPOMapper.selectList(queryWrapper);
        List<AreaOrganizationVO> areaOrganizationVOList = new ArrayList<>(areaOrganizationPOS.size());
        CustomBeanUtils.convertPojo(areaOrganizationPOS,areaOrganizationVOList,AreaOrganizationVO.class);
        return areaOrganizationVOList;
    }

    @Override
    public List<Long> getAllChildAreaIds(Integer areaId) {
        List<Long> childAreaIds = getChildAreaIdsWithoutRights(areaId);
        List<AreaOrganizationVO> areaOrganizationVOs = getAreaOrganizationVOs();
        List<Long> userRightsArea = areaOrganizationVOs.stream().map(AreaOrganizationVO::getId).collect(Collectors.toList());
        childAreaIds.containsAll(userRightsArea);
        return childAreaIds;
    }

    private List<Long> getChildAreaIdsWithoutRights(Integer areaId){
        AreaOrganizationPO areaOrganizationPO = areaOrganizationPOMapper.selectById(areaId);
        List<Long> res = new ArrayList<>();
        addChildAreaId(areaOrganizationPO,res);
        return res;
    }

    @Override
    public Map<Long, String> getAreaNamesById(List<Long> areaIds) {
        if(areaIds.isEmpty()){
            return new HashMap<>(0);
        }
        QueryWrapper<AreaOrganizationPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",areaIds);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        List<AreaOrganizationPO> areaOrganizationPOS = areaOrganizationPOMapper.selectList(queryWrapper);
        return areaOrganizationPOS.stream()
                .collect(Collectors.toMap(AreaOrganizationPO::getId,AreaOrganizationPO::getName));
    }

    /**
     * 递归获取该节点下所有节点
     * @param areaOrganizationPO
     * @param res
     */
    private void addChildAreaId(AreaOrganizationPO areaOrganizationPO, List<Long> res){
        if(areaOrganizationPO == null){
            return;
        }
        res.add(areaOrganizationPO.getId());
        QueryWrapper<AreaOrganizationPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",areaOrganizationPO.getId());
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        List<AreaOrganizationPO> children = areaOrganizationPOMapper.selectList(queryWrapper);
        for (AreaOrganizationPO child : children) {
            addChildAreaId(child,res);
        }
    }

    @Override
    public PageVO<AreaOrganizationPageVO> getAreaOrganizationPageVOs(String areaSerialnumber, String name, Integer pageSize, Integer pageNo, String orderColumn, String orderType) {
        IPage<AreaOrganizationPO> page = new Page<>(pageNo, pageSize);
        QueryWrapper<AreaOrganizationPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(areaSerialnumber)) {
            queryWrapper.like("area_serialnumber", areaSerialnumber.trim());
        }
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("name", name.trim());
        }
        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        IPage<AreaOrganizationPO> equipmentmodelPOIPage = areaOrganizationPOMapper.selectPage(page, queryWrapper);
        PageVO<AreaOrganizationPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNo);
        List<AreaOrganizationPageVO> roleVOList = convertToAreaOrganizationPageVOList(equipmentmodelPOIPage.getRecords(), pageSize, pageNo);
        pageVO.setData(roleVOList);
        pageVO.setTotal(equipmentmodelPOIPage.getTotal());
        pageVO.setPages(equipmentmodelPOIPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(AREA_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 对象转换
     *
     * @param records
     * @return
     */
    private List<AreaOrganizationPageVO> convertToAreaOrganizationPageVOList(List<AreaOrganizationPO> records, Integer pageSize, Integer pageNo) {
        List<AreaOrganizationPageVO> res = new ArrayList<>(records.size());
        AreaOrganizationPageVO metermodelPageVO;

        int i = pageSize * (pageNo - 1) + 1;
        for (AreaOrganizationPO record : records) {
            metermodelPageVO = new AreaOrganizationPageVO();
            metermodelPageVO.setSerialNum(i);
            metermodelPageVO.setId(record.getId());
            metermodelPageVO.setAreaSerialnumber(record.getAreaSerialnumber());
            metermodelPageVO.setName(record.getName());
            metermodelPageVO.setAreaContactName(record.getAreaContactName());
            metermodelPageVO.setAreaContactPhone(record.getAreaContactPhone());
            metermodelPageVO.setIsSendSmsName(SystemConsts.YesOrNoEnum.getNameByValue(record.getIsSendSms()));
            metermodelPageVO.setIsDaySettlementName(SystemConsts.YesOrNoEnum.getNameByValue(record.getIsDaySettlement()));
            metermodelPageVO.setSettlementDay(record.getSettlementDay());
            res.add(metermodelPageVO);
            i++;
        }
        return res;
    }

    @Override
    public Long add(AreaOrganizationSaveDTO areaOrganizationSaveDTO) {
        if (StrUtil.isBlank(areaOrganizationSaveDTO.getAreaSerialnumber()) ||
                StrUtil.isBlank(areaOrganizationSaveDTO.getName())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        //邮箱合法性校验，可以为空，不为空格式需符合要求
        if (StrUtil.isNotBlank(areaOrganizationSaveDTO.getAreaContactMail()) &&
                !CustomStrUtil.isEmail(areaOrganizationSaveDTO.getAreaContactMail())) {
            throw new MyException(ResponseCode.EMAIL_FORMAT_ERROR);
        }

        AreaOrganizationPO areaOrganizationPO = new AreaOrganizationPO();
        areaOrganizationPO.setCompanyId(0L);
        areaOrganizationPO.setCreateDate(new Date());
        areaOrganizationPO.setEnergyType(SystemConsts.EnergyTypeEnum.WATER.value);
        areaOrganizationPO.setIsDel(SystemConsts.BooleanEnum.FALSE.value);
        areaOrganizationPO.setModifyDate(new Date());
        areaOrganizationPO.setOperatorId(1L);
        areaOrganizationPO.setAreaContactMail(areaOrganizationSaveDTO.getAreaContactMail());
        areaOrganizationPO.setAreaContactName(areaOrganizationSaveDTO.getAreaContactName());
        areaOrganizationPO.setAreaContactPhone(areaOrganizationSaveDTO.getAreaContactPhone());
        areaOrganizationPO.setAreaContactTel(areaOrganizationSaveDTO.getAreaContactTel());
        areaOrganizationPO.setAreaMapLatitude(areaOrganizationSaveDTO.getAreaMapLatitude());
        areaOrganizationPO.setAreaMapLongitude(areaOrganizationSaveDTO.getAreaMapLongitude());
        areaOrganizationPO.setName(areaOrganizationSaveDTO.getName());
        areaOrganizationPO.setParentId(areaOrganizationSaveDTO.getParentId());
        areaOrganizationPO.setAreaSerialnumber(areaOrganizationSaveDTO.getAreaSerialnumber());
        areaOrganizationPO.setIsDaySettlement(areaOrganizationSaveDTO.getIsDaySettlement());
        areaOrganizationPO.setIsSendSms(areaOrganizationSaveDTO.getIsSendSms());
        areaOrganizationPO.setSettlementDay(areaOrganizationSaveDTO.getSettlementDay());

        areaOrganizationPOMapper.insert(areaOrganizationPO);
        return areaOrganizationPO.getId();
    }

    @Override
    public boolean update(AreaOrganizationSaveDTO areaOrganizationSaveDTO) {
        if (StrUtil.isBlank(areaOrganizationSaveDTO.getAreaSerialnumber()) ||
                StrUtil.isBlank(areaOrganizationSaveDTO.getName())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        //邮箱合法性校验，可以为空，不为空格式需符合要求
        if (StrUtil.isNotBlank(areaOrganizationSaveDTO.getAreaContactMail()) &&
                !CustomStrUtil.isEmail(areaOrganizationSaveDTO.getAreaContactMail())) {
            throw new MyException(ResponseCode.EMAIL_FORMAT_ERROR);
        }

        AreaOrganizationPO areaOrganizationPO = new AreaOrganizationPO();
        areaOrganizationPO.setId(areaOrganizationSaveDTO.getId());
        areaOrganizationPO.setModifyDate(new Date());
        areaOrganizationPO.setOperatorId(1L);
        areaOrganizationPO.setAreaContactMail(areaOrganizationSaveDTO.getAreaContactMail());
        areaOrganizationPO.setAreaContactName(areaOrganizationSaveDTO.getAreaContactName());
        areaOrganizationPO.setAreaContactPhone(areaOrganizationSaveDTO.getAreaContactPhone());
        areaOrganizationPO.setAreaContactTel(areaOrganizationSaveDTO.getAreaContactTel());
        areaOrganizationPO.setAreaMapLatitude(areaOrganizationSaveDTO.getAreaMapLatitude());
        areaOrganizationPO.setAreaMapLongitude(areaOrganizationSaveDTO.getAreaMapLongitude());
        areaOrganizationPO.setName(areaOrganizationSaveDTO.getName());
        areaOrganizationPO.setParentId(areaOrganizationSaveDTO.getParentId());
        areaOrganizationPO.setAreaSerialnumber(areaOrganizationSaveDTO.getAreaSerialnumber());
        areaOrganizationPO.setIsDaySettlement(areaOrganizationSaveDTO.getIsDaySettlement());
        areaOrganizationPO.setIsSendSms(areaOrganizationSaveDTO.getIsSendSms());
        areaOrganizationPO.setSettlementDay(areaOrganizationSaveDTO.getSettlementDay());

        areaOrganizationPOMapper.updateById(areaOrganizationPO);
        return true;
    }

    @Override
    public boolean delete(List<Integer> ids) {
        if(CollUtil.isEmpty(ids)){
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        //供应商表逻辑删除
        QueryWrapper<AreaOrganizationPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        AreaOrganizationPO areaOrganizationPO = new AreaOrganizationPO();
        areaOrganizationPO.setIsDel(SystemConsts.BooleanEnum.TRUE.value);
        int num = areaOrganizationPOMapper.update(areaOrganizationPO,queryWrapper);

        return num > 0;
    }

    @Override
    public AreaOrganizationSaveDTO getAreaOrganization(Integer id) {
        AreaOrganizationPO areaOrganizationPO = areaOrganizationPOMapper.selectById(id);
        if(areaOrganizationPO==null||SystemConsts.BooleanEnum.TRUE.value.equals(areaOrganizationPO.getIsDel())){
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }

        AreaOrganizationSaveDTO areaOrganizationSaveDTO = new AreaOrganizationSaveDTO();
        areaOrganizationSaveDTO.setId(areaOrganizationPO.getId());
        areaOrganizationSaveDTO.setAreaContactMail(areaOrganizationPO.getAreaContactMail());
        areaOrganizationSaveDTO.setAreaContactName(areaOrganizationPO.getAreaContactName());
        areaOrganizationSaveDTO.setAreaContactPhone(areaOrganizationPO.getAreaContactPhone());
        areaOrganizationSaveDTO.setAreaContactTel(areaOrganizationPO.getAreaContactTel());
        areaOrganizationSaveDTO.setAreaMapLatitude(areaOrganizationPO.getAreaMapLatitude());
        areaOrganizationSaveDTO.setAreaMapLongitude(areaOrganizationPO.getAreaMapLongitude());
        areaOrganizationSaveDTO.setName(areaOrganizationPO.getName());
        areaOrganizationSaveDTO.setParentId(areaOrganizationPO.getParentId());
        areaOrganizationSaveDTO.setAreaSerialnumber(areaOrganizationPO.getAreaSerialnumber());
        areaOrganizationSaveDTO.setIsDaySettlement(areaOrganizationPO.getIsDaySettlement());
        areaOrganizationSaveDTO.setIsSendSms(areaOrganizationPO.getIsSendSms());
        areaOrganizationSaveDTO.setSettlementDay(areaOrganizationPO.getSettlementDay());

        return areaOrganizationSaveDTO;
    }

    @Override
    public Map<String, List<EnumVO>> getEnums() {
        Map<String, List<EnumVO>> resultMap = new HashMap<>();

        List<EnumVO> yesOrNo = new ArrayList<>();
        for (SystemConsts.YesOrNoEnum value : SystemConsts.YesOrNoEnum.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            yesOrNo.add(vo);
        }

        List<EnumVO> settlementDay = new ArrayList<>();
        for (SystemConsts.SettlementDay value : SystemConsts.SettlementDay.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            settlementDay.add(vo);
        }

        resultMap.put("yesOrNo", yesOrNo);
        resultMap.put("settlementDay", settlementDay);
        return resultMap;
    }
}
